package com.evil.kingdom.handler;

import com.alibaba.fastjson.JSONException;
import com.evil.common.core.entity.R;
import com.evil.common.core.exception.BusinessException;
import com.evil.kingdom.pojo.enums.result.RCodeEnum;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.ValidationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

@Slf4j
@RestControllerAdvice(basePackages = "com.evil.kingdom.controller")
public class WebGlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler({BusinessException.class})
    public R<?> handleException(BusinessException e) {
        log.error(e.getMessage());
        return R.error(e.getCode(), e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler({ValidationException.class, ConstraintViolationException.class})
    public R<?> handleException(ValidationException e) {
        log.error(e.getMessage(), e);
        return R.error(RCodeEnum.ERROR_PARAMETER, e.getMessage().split(": ")[1]);
    }

    @ResponseBody
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public R<?> handleException(MethodArgumentNotValidException e) {
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        String errorMessage = fieldErrors.get(0).getDefaultMessage();
        log.error(errorMessage, e);
        return R.error(RCodeEnum.ERROR_PARAMETER.getCode(), errorMessage);
    }

    @ResponseBody
    @ExceptionHandler({BindException.class})
    public R<?> handleException(BindException e) {
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        String errorMessage = fieldErrors.get(0).getDefaultMessage();
        log.error(errorMessage, e);
        return R.error(RCodeEnum.ERROR_PARAMETER.getCode(), errorMessage);
    }

    @ResponseBody
    @ExceptionHandler({RuntimeException.class})
    public R<?> handleException(RuntimeException e) {
        log.error(e.getMessage(), e);
        if (null != e.getCause()) {
            if (e.getCause() instanceof JSONException) {
                return R.error(RCodeEnum.ERROR, e.getMessage());
            }
        }
        return R.error(RCodeEnum.ERROR);
    }

    @ResponseBody
    @ExceptionHandler({Exception.class})
    public R<?> handleException(Exception e) {
        log.error(e.getMessage(), e);
        return R.error(e.getMessage());
    }
}
